package com.maxbill.fxui.mian;

import com.maxbill.fxui.body.BodyWindow;
import com.maxbill.fxui.foot.FootWindow;
import com.maxbill.fxui.head.HeadWindow;
import com.maxbill.fxui.left.LeftWindow;
import javafx.scene.Cursor;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import lombok.extern.log4j.Log4j2;

import static com.maxbill.fxui.util.CommonConstant.STYLE_MAIN;
import static com.maxbill.fxui.util.DesktopObjects.*;


/**
 * 主窗口
 *
 * @author MaxBill
 * @date 2019/07/06
 */
@Log4j2
public class MainWindow {

    /**
     * 组装主窗口
     */
    public static BorderPane getMainWindow() {
        BorderPane mainWindow = new BorderPane();
        mainWindow.setId("main-pane");
        mainWindow.getStylesheets().add(STYLE_MAIN);
        mainWindow.setTop(HeadWindow.getHeadWindow());
        mainWindow.setLeft(LeftWindow.getLeftWindow());
        mainWindow.setCenter(BodyWindow.getBodyWindow());
        mainWindow.setBottom(FootWindow.getFootWindow());
        return mainWindow;
    }

    /**
     * 监听窗口操作事件
     */
    public static void mainListener() {
        //监听窗口移动后事件
        mainMouseMoved();
        //监听窗口拖拽后事件
        mainMouseDragged();
        //监听鼠标点击后事件
        mainMousePressed();
    }

    /**
     * 监听窗口移动后事件
     */
    private static void mainMouseMoved() {
        //监听窗口移动后事件
        mainWin.setOnMouseMoved((MouseEvent event) -> {
            if (IS_MAX || IS_FULL) {
                return;
            }
            event.consume();
            double x = event.getSceneX();//记录x数据
            double y = event.getSceneY();//记录y数据
            double w = rootWin.getWidth();//记录width数据
            double h = rootWin.getHeight();//记录height数据
            //光标初始为默认类型，若未进入调整窗口状态则保持默认类型
            Cursor cursorType = Cursor.DEFAULT;
            //将所有调整窗口状态重置
            IS_RIGHT = IS_BOTTOM_RIGHT = IS_BOTTOM = false;
            if (y >= h - RESIZE_WIDTH) {
                if (x >= w - RESIZE_WIDTH) {
                    //右下角调整窗口状态
                    IS_BOTTOM_RIGHT = true;
                    cursorType = Cursor.SE_RESIZE;
                } else {
                    //下边界调整窗口状态
                    IS_BOTTOM = true;
                    cursorType = Cursor.S_RESIZE;
                }
            } else if (x >= w - RESIZE_WIDTH) {
                // 右边界调整窗口状态
                IS_RIGHT = true;
                cursorType = Cursor.E_RESIZE;
            }
            // 最后改变鼠标光标
            mainWin.setCursor(cursorType);
        });
    }

    /**
     * 监听窗口拖拽后事件
     */
    private static void mainMouseDragged() {
        //监听窗口拖拽后事件
        mainWin.setOnMouseDragged((MouseEvent event) -> {
            event.consume();
            if (Y_OFFSET != 0) {
                rootWin.setX(event.getScreenX() - X_OFFSET);
                if (event.getScreenY() - Y_OFFSET < 0) {
                    rootWin.setY(0);
                } else {
                    rootWin.setY(event.getScreenY() - Y_OFFSET);
                }
            }
            //保存窗口改变后的x、y坐标和宽度、高度，用于预判是否会小于最小宽度、最小高度
            double x = rootWin.getX();
            double y = rootWin.getY();
            double w = rootWin.getWidth();
            double h = rootWin.getHeight();
            if (IS_RIGHT || IS_BOTTOM_RIGHT) {
                // 所有右边调整窗口状态
                w = event.getSceneX();
            }
            if (IS_BOTTOM_RIGHT || IS_BOTTOM) {
                // 所有下边调整窗口状态
                h = event.getSceneY();
            }
            if (w <= MIN_W) {
                // 如果窗口改变后的宽度小于最小宽度，则宽度调整到最小宽度
                w = MIN_W;
            }
            if (h <= MIN_H) {
                // 如果窗口改变后的高度小于最小高度，则高度调整到最小高度
                h = MIN_H;
            }
            // 最后统一改变窗口的x、y坐标和宽度、高度，可以防止刷新频繁出现的屏闪情况
            rootWin.setX(x);
            rootWin.setY(y);
            rootWin.setWidth(w);
            rootWin.setHeight(h);
        });
    }

    /**
     * 鼠标点击获取横纵坐标
     */
    private static void mainMousePressed() {
        mainWin.setOnMousePressed(event -> {
            event.consume();
            X_OFFSET = event.getSceneX();
            if (event.getSceneY() > MIN_SCENE) {
                Y_OFFSET = 0;
            } else {
                Y_OFFSET = event.getSceneY();
            }
        });
    }

}
